﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MangaReader.MangaService;
using System.Net;
using System.IO;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Text.RegularExpressions;
using System.Xml;
using System.Threading;

namespace MangaReader
{
    public partial class ToolForKissMangaForm : Form
    {
        MangaServiceClient service = new MangaServiceClient();
        MangaCollectionContract mangaList = new MangaCollectionContract();
        MangaStoryDetailContract manga;
        string suggestTitle = "";
        string pathSaveTo;
        string pathOfImageFolder;
        string pathOfCopyFilesFolder;

        string findValue = "";
        string replaceValue = "";

        // C:\Users\Tuan\Desktop\CopyFiles_0313
        string pathCopyFrom;

        public ToolForKissMangaForm()
        {
            InitializeComponent();
            pathCopyFrom = this.txtCopyFrom.Text;
            //pathSaveTo = this.txtSaveTo.Text;

            //pathOfImageFolder = pathSaveTo + "\\Images";
            //pathOfCopyFilesFolder = pathSaveTo + "\\CopyFiles";

            findValue = this.txtFindValue.Text;
        }

        public MangaStoryDetailContract getManga()
        {
            string url = this.txtUrl.Text;
            KissManga kiss = new KissManga(url);
            return kiss.GetManga();
        }

        private void btnGetDetail_Click(object sender, EventArgs e)
        {
            if (this.txtUrl.Text == "")
            {
                MessageBox.Show("Quên nhập đường dẫn cho TRUYỆN rồi mầy ơi!");
                this.txtUrl.Focus();
                return;
            }

            if (this.txtSaveTo.Text == "" || this.txtCopyFrom.Text == "")
            {
                MessageBox.Show("Quên nhập đường dẫn cho FOLDER rồi mầy ơi!");
                return;
            }
            //if (manga == null)
            //{
            // http://truyen.vnsharing.net/Truyen/High-School-continued
            string url = this.txtUrl.Text;
            KissManga kiss = new KissManga(url);
            manga = kiss.GetManga();
            //ToolForKissMangaForm testThread = new ToolForKissMangaForm();
            //Thread t = new Thread();          // Kick off a new thread

            //t.Start();  
            

            // Make sure return value is correct 
            if (manga.ImageLink == null || manga.ImageLink == "")
            {
                try
                {
                    manga.ImageLink = kiss.GetImageLink(url);
                }
                catch (Exception ex)
                {
                    manga.ImageLink = "";
                    MessageBox.Show(ex.Message);
                }
            }

            manga.Summary = SearchAndReplace(manga.Summary, @"&[^;]*;", "");

            if (manga.Author == null)
            {
                manga.Author = "IAmABotAuthor";
            }

            if (manga.Title == null)
            {
                manga.Title = "IAmABotTitle";
            }

            //////////////////////////////////////////////

            
            try
            {
                // Update GUI
                this.txtTitle.Text = manga.Title;
                suggestTitle = GetSuggestTitle(manga.Title);

                this.txtSuggestTitle.Text = suggestTitle;
                replaceValue = this.txtSuggestTitle.Text;

                this.txtAuthor.Text = manga.Author;
                this.txtImageLink.Text = manga.ImageLink;
                this.txtSummary.Text = manga.Summary;


                pathSaveTo = this.txtSaveTo.Text + "\\" + suggestTitle;
                pathOfImageFolder = pathSaveTo + "\\" + "Images";
                pathOfCopyFilesFolder = pathSaveTo + "\\" + "CopyFiles";

                // Work with FILE/DIRECTORY
                CreateFolders();
                CopyFiles();
                EditCopiedFiles();

                // Work with images
                CreateImages(manga.ImageLink);

                MoveMangaImageToCopyFileImageFolder();


            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void EditCopiedFiles()
        {
            EditXMLFile();
            EditXAMLFiles();

            // Insert manga link to app.xam.cs

        }

        private void EditXAMLFiles()
        {
            EditFileUsingSearchAndReplace(pathOfCopyFilesFolder + "\\ViewModel\\DBViewModel.cs", findValue, replaceValue);

            EditFileUsingSearchAndReplace(pathOfCopyFilesFolder + "\\Class\\ChapterDownload.cs", findValue, replaceValue);

            EditFileUsingSearchAndReplace(pathOfCopyFilesFolder + "\\App.xaml", findValue, replaceValue);
            EditFileUsingSearchAndReplace(pathOfCopyFilesFolder + "\\App.xaml.cs", findValue, replaceValue);
            // ?confirm=yes
            EditFileUsingSearchAndReplace(pathOfCopyFilesFolder + "\\App.xaml.cs", "LinkMangaHere",
                            String.Format("{0}?confirm=yes", manga.Link));

            EditFileUsingSearchAndReplace(pathOfCopyFilesFolder + "\\ChaptersPage.xaml", findValue, replaceValue);
            EditFileUsingSearchAndReplace(pathOfCopyFilesFolder + "\\ChaptersPage.xaml.cs", findValue, replaceValue);

            EditFileUsingSearchAndReplace(pathOfCopyFilesFolder + "\\ContentPage.xaml", findValue, replaceValue);
            EditFileUsingSearchAndReplace(pathOfCopyFilesFolder + "\\ContentPage.xaml.cs", findValue, replaceValue);

            EditFileUsingSearchAndReplace(pathOfCopyFilesFolder + "\\IntroPage.xaml", findValue, replaceValue);
            EditFileUsingSearchAndReplace(pathOfCopyFilesFolder + "\\IntroPage.xaml.cs", findValue, replaceValue);
        }

        private void EditFileUsingSearchAndReplace(string path, string findValue, string replaceValue)
        {
            StreamReader streamReader = new StreamReader(path);
            string text = streamReader.ReadToEnd();
            streamReader.Close();
            streamReader.Dispose();

            text = SearchAndReplace(text, findValue, replaceValue);

            File.WriteAllText(path, text);
        }

        private void EditXMLFile()
        {
            try
            {
                string xmlFile = pathOfCopyFilesFolder + "\\OriginalData.xml";
                XmlDocument xmlDoc = new XmlDocument();

                xmlDoc.Load(xmlFile);

                XmlNode node;
                // Edit title
                node = xmlDoc.SelectSingleNode("Root/Manga/Title");
                node.InnerXml = manga.Title;

                // Edit Author
                node = xmlDoc.SelectSingleNode("Root/Manga/Author");
                node.InnerXml = manga.Author;

                // Edit Summary
                node = xmlDoc.SelectSingleNode("Root/Manga/Summary");
                
                //manga.Summary = Regex.Replace(manga.Summary, @"^""|""$|\\n?", "");
                //string tmp = manga.Summary;
                //MessageBox.Show(Regex.Replace(manga.Summary, @"^""|""$|\\n?", ""));
                //node.InnerXml = Regex.Replace(manga.Summary, @"^""|""$|\\n?", "");
                node.InnerXml = manga.Summary;

                // Edit Link
                node = xmlDoc.SelectSingleNode("Root/Manga/Link");
                node.InnerXml = manga.Link;

                // Edit ImageLink
                node = xmlDoc.SelectSingleNode("Root/Manga/ImageLink");
                node.InnerXml = manga.ImageLink;

                // Inser chapters
                foreach (MangaChapter chap in manga.Chapters)
                {
                    XmlNode chapNode = xmlDoc.CreateNode("element", "Chapter", "");

                    XmlNode titleNode = xmlDoc.CreateNode("element", "Title", "");
                    titleNode.InnerXml = chap.Title;
                    chapNode.AppendChild(titleNode);

                    XmlNode linkNode = xmlDoc.CreateNode("element", "Link", "");
                    linkNode.InnerXml = chap.Link;
                    chapNode.AppendChild(linkNode);
                    //XmlNode dateNode = xmlDoc.CreateNode("element", "Date", "");
                    //dateNode.InnerXml = chap.Date;

                    XmlNode chapters = xmlDoc.SelectSingleNode("Root/Manga/Chapters");
                    chapters.AppendChild(chapNode);
                }

                xmlDoc.Save(xmlFile);
            }
            catch (Exception ex)
            {

            }
        }

        private void MoveMangaImageToCopyFileImageFolder()
        {
            try
            {
                string oldPath = pathOfImageFolder + "\\MangaImage.jpg";
                string newPath = pathOfCopyFilesFolder + "\\Images\\MangaImage.jpg";
                if (File.Exists(newPath) == false)
                {
                    File.Move(oldPath, newPath);
                }
                else
                {
                    File.Delete(newPath);
                    File.Move(oldPath, newPath);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void CopyFiles()
        {
            // Check manga folder
            if (Directory.Exists(pathCopyFrom) == true)
            {
                string[] folderNames = Directory.GetDirectories(pathCopyFrom);
                // Copy files in root folder
                // Check files
                string[] rootFileNames = Directory.GetFiles(pathCopyFrom);

                foreach (string fileName in rootFileNames)
                {
                    string nameFile = fileName.Substring(fileName.LastIndexOf("\\") + 1);
                    string pathFile = pathOfCopyFilesFolder + "\\" + nameFile;
                    if (File.Exists(pathFile) == false)
                    {
                        File.Copy(fileName, pathFile);
                    }
                }


                foreach (string folderName in folderNames)
                {
                    string nameFolder = folderName.Substring(folderName.LastIndexOf("\\") + 1);
                    string pathFolder = pathOfCopyFilesFolder + "\\" + nameFolder;

                    // Create folder
                    if (Directory.Exists(pathFolder) == false)
                    {
                        Directory.CreateDirectory(pathFolder);
                    }

                    // Check files
                    string[] fileNames = Directory.GetFiles(folderName);

                    foreach (string fileName in fileNames)
                    {
                        string nameFile = fileName.Substring(fileName.LastIndexOf("\\") + 1);
                        string pathFile = pathOfCopyFilesFolder + "\\" + nameFolder + "\\" + nameFile;

                        if (File.Exists(pathFile) == false)
                        {
                            File.Copy(fileName, pathFile);
                        }
                    }
                }
            }
        }

        private void CreateFolders()
        {
            // Check manga folder
            if (Directory.Exists(pathSaveTo) == false)
            {
                Directory.CreateDirectory(pathSaveTo);
            }

            // Check Image folder
            if (Directory.Exists(pathOfImageFolder) == false)
            {
                Directory.CreateDirectory(pathOfImageFolder);
            }

            // Check CopyFiles folder
            if (Directory.Exists(pathOfCopyFilesFolder) == false)
            {
                Directory.CreateDirectory(pathOfCopyFilesFolder);
            }
        }

        private string SearchAndReplace(string text, string find, string replace)
        {
            try
            {
                Regex rgx = new Regex(find, RegexOptions.IgnoreCase);
                //MatchCollection matches = rgx.Matches(text);
                //rgx.IsMatch(text);

                return rgx.Replace(text, replace);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return text;
            }
        }

        private string GetSuggestTitle(string oldTitle)
        {
            string tmp = SearchAndReplace(oldTitle, @"[^(a-z)(0-9)]", "");
            tmp = SearchAndReplace(tmp, @"[()]", "");


            return tmp;
            //string newTitle;
            //string pattern = @"[^(a-z)(0-9)]";
            //string replacement = "";
            //Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);

            //newTitle = rgx.Replace(oldTitle, replacement);
            //return newTitle;
        }

        #region IMAGES
        private void CreateImages(string url)
        {
            WebClient webGetImage = new WebClient();
            string strRoot = pathSaveTo + "\\Images";
            Image mangaImage = Image.FromStream(webGetImage.OpenRead(url));

            Bitmap imageManga;
            imageManga = (Bitmap)resizeImage(mangaImage, new Size(190, 250));
            saveJpeg(strRoot + "\\MangaImage.jpg", imageManga, 50, "image/jpeg");

            Bitmap splashScreen;
            splashScreen = (Bitmap)resizeImage(mangaImage, new Size(480, 800));
            saveJpeg(strRoot + "\\SplashScreenImage.jpg", splashScreen, 50, "image/jpeg");

            Bitmap screenShot3;
            screenShot3 = (Bitmap)resizeImage(mangaImage, new Size(480, 800));
            saveJpeg(strRoot + "\\3ScreenShot.png", screenShot3, 50, "image/png");

            Bitmap large;
            large = (Bitmap)resizeImage(mangaImage, new Size(200, 200));
            saveJpeg(strRoot + "\\200.png", large, 50, "image/png");

            Bitmap small;
            small = (Bitmap)resizeImage(mangaImage, new Size(99, 99));
            saveJpeg(strRoot + "\\99.png", small, 50, "image/png");

            Bitmap background;
            background = (Bitmap)resizeImage(mangaImage, new Size(173, 173));
            saveJpeg(strRoot + "\\Background.png", background, 50, "image/png");

            Bitmap appIcon;
            appIcon = (Bitmap)resizeImage(mangaImage, new Size(62, 62));
            saveJpeg(strRoot + "\\ApplicationIcon.png", appIcon, 50, "image/png");

            Bitmap arkBG;
            arkBG = (Bitmap)resizeImage(mangaImage, new Size(1000, 800));
            saveJpeg(strRoot + "\\1000.png", arkBG, 50, "image/png");
        }

        private static Image resizeImage(Image imgToResize, Size size)
        {
            int sourceWidth = imgToResize.Width;
            int sourceHeight = imgToResize.Height;

            float nPercent = 0;
            float nPercentW = 0;
            float nPercentH = 0;

            nPercentW = (Convert.ToSingle(size.Width) / Convert.ToSingle(sourceWidth));
            nPercentH = (Convert.ToSingle(size.Height) / Convert.ToSingle(sourceHeight));

            if (nPercentH < nPercentW)
            {
                nPercent = nPercentH;
            }
            else
            {
                nPercent = nPercentW;
            }

            int destWidth = Convert.ToInt32(Math.Truncate(sourceWidth * nPercent));
            int destHeight = Convert.ToInt32(Math.Truncate(sourceHeight * nPercent));

            Bitmap b = new Bitmap(size.Width, size.Height);
            Graphics g = Graphics.FromImage((Image)b);
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;

            //g.DrawImage(imgToResize, 0, 0, destWidth, destHeight)
            g.DrawImage(imgToResize, 0, 0, size.Width, size.Height);
            g.Dispose();

            return (Image)b;
        }

        private void saveJpeg(string path, Bitmap img, long quality, string codecInfo)
        {
            // Encoder parameter for image quality
            EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);

            // Jpeg image codec
            ImageCodecInfo jpegCodec = this.getEncoderInfo(codecInfo);

            if (jpegCodec == null)
            {
                return;
            }

            EncoderParameters encoderParams = new EncoderParameters(1);
            encoderParams.Param[0] = qualityParam;

            img.Save(path, jpegCodec, encoderParams);
        }

        private ImageCodecInfo getEncoderInfo(string mimeType)
        {
            // Get image codecs for all image formats
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

            // Find the correct image codec
            for (int i = 0; i <= codecs.Length - 1; i++)
            {
                if (codecs[i].MimeType == mimeType)
                {
                    return codecs[i];
                }
            }
            return null;
        }
        #endregion

        #region Handle
        private void txtSuggestTitle_MouseClick(object sender, MouseEventArgs e)
        {
            this.txtSuggestTitle.SelectAll();
        }

        private void btnCopyFrom_Click(object sender, EventArgs e)
        {
            this.folderBrowserDialog.ShowDialog();
            this.txtCopyFrom.Text = this.folderBrowserDialog.SelectedPath;
            this.pathCopyFrom = this.txtCopyFrom.Text;
        }

        private void btnSaveTo_Click(object sender, EventArgs e)
        {
            this.folderBrowserDialog.ShowDialog();
            this.txtSaveTo.Text = this.folderBrowserDialog.SelectedPath;
            this.pathSaveTo = this.txtSaveTo.Text;
        }

        private void txtTitle_MouseClick(object sender, MouseEventArgs e)
        {
            this.txtTitle.SelectAll();
        }

        private void txtAuthor_MouseClick(object sender, MouseEventArgs e)
        {
            this.txtAuthor.SelectAll();
        }

        private void txtImageLink_MouseClick(object sender, MouseEventArgs e)
        {
            this.txtImageLink.SelectAll();
        }

        private void txtSummary_MouseClick(object sender, MouseEventArgs e)
        {
            this.txtSummary.SelectAll();
        }

        #endregion
        
    }
}
